package com.atguigu.common.utils;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Charsets;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.CharsetUtils;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ReflectionUtils;

public class HttpClient {
    private static final Logger log = LoggerFactory.getLogger(HttpClient.class);

    private static final Charset charset = Charsets.UTF_8;

    // 编码格式。发送编码格式统一用UTF-8
    private static final String ENCODING = Charsets.UTF_8.name();
    private static final CloseableHttpClient closeableHttpClient;

    static {
      RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(20000)
          .setConnectionRequestTimeout(5000).build();

      closeableHttpClient =
          HttpClients.custom().setDefaultRequestConfig(requestConfig).setMaxConnTotal(200).setMaxConnPerRoute(100)
              .evictExpiredConnections().setRetryHandler(new DefaultHttpRequestRetryHandler(0, false))
              .evictIdleConnections(1L, TimeUnit.MINUTES).build();

      Runtime.getRuntime().addShutdownHook(new Thread() {
        @Override
        public void run() {
          try {
            closeableHttpClient.close();
          } catch (IOException e) {
            e.printStackTrace();
          }
        }
      });
    }

    /**
     * @param url
     *            提交的URL
     * @param paramsMap
     *            提交<参数，值>Map
     * @return 提交响应
     */

    public static String post(String url, Map<String, String> paramsMap) {
      CloseableHttpResponse response = null;
      try {
        HttpPost method = new HttpPost(url);
        if (paramsMap != null) {
          List<NameValuePair> paramList = new ArrayList<NameValuePair>();
          for (Map.Entry<String, String> param : paramsMap.entrySet()) {
            NameValuePair pair = new BasicNameValuePair(param.getKey(), param.getValue());
            paramList.add(pair);
          }
          method.setEntity(new UrlEncodedFormEntity(paramList, ENCODING));
        }
        response = closeableHttpClient.execute(method);
        if (response.getStatusLine().getStatusCode() == 200) {
          HttpEntity entity = response.getEntity();
          if (entity != null) {
            return EntityUtils.toString(entity);
          }
        } else {
          log.error("当前请求响应码：" + response.getStatusLine().getStatusCode());
        }
      } catch (Exception e) {
        log.error("", e);
      } finally {
        try {
          if (response != null) {
            response.close();
          }
        } catch (Exception e) {
          log.error("", e);
        }
      }
      return null;
    }

    public static String post(String url, String params) {
      CloseableHttpResponse response = null;
      try {
        HttpPost httpPost = new HttpPost(url);
        httpPost.setHeader("content-type", "application/json");
        HttpEntity reqentity = new StringEntity(params, charset);
        httpPost.setEntity(reqentity);
        response = closeableHttpClient.execute(httpPost);
        if (response.getStatusLine().getStatusCode() == 200) {
          HttpEntity entity = response.getEntity();
          if (entity != null) {
            return EntityUtils.toString(entity, ENCODING);
          }
        }
      } catch (Exception e) {
        log.error("", e);
      } finally {
        try {
          if (response != null) {
            response.close();
          }
        } catch (IOException e) {
          log.error("", e);
        }
      }
      return null;
    }

    public static String postWithTimeOutParm(String url, String params, Integer connectTimeout,
        Integer connectionRequestTimeout, Integer socketTimeout) {
      CloseableHttpResponse response = null;
      try {
        HttpPost httpPost = new HttpPost(url);
        RequestConfig requestConfig =
            RequestConfig.custom().setConnectTimeout(connectTimeout == null ? 35000 : connectTimeout)// 设置连接主机服务超时时间
                .setConnectionRequestTimeout(connectionRequestTimeout == null ? 35000 : connectionRequestTimeout)// 设置连接请求超时时间
                .setSocketTimeout(socketTimeout == null ? 60000 : socketTimeout)// 设置读取数据连接超时时间
                .build();
        // 为httpPost实例设置配置
        httpPost.setConfig(requestConfig);
        httpPost.setHeader("content-type", "application/json");
        HttpEntity reqentity = new StringEntity(params, charset);
        httpPost.setEntity(reqentity);
        response = closeableHttpClient.execute(httpPost);
        if (response.getStatusLine().getStatusCode() == 200) {
          HttpEntity entity = response.getEntity();
          if (entity != null) {
            return EntityUtils.toString(entity, ENCODING);
          }
        }
      } catch (Exception e) {
        log.error("", e);
      } finally {
        try {
          if (response != null) {
            response.close();
          }
        } catch (IOException e) {
          log.error("", e);
        }
      }
      return null;
    }


    public static String postWithTimeOutParm(String url, Map<String,String> paramsMap, Integer connectTimeout,
        Integer connectionRequestTimeout, Integer socketTimeout) {
      CloseableHttpResponse response = null;
      try {
        HttpPost httpPost = new HttpPost(url);
        RequestConfig requestConfig =
            RequestConfig.custom().setConnectTimeout(connectTimeout == null ? 35000 : connectTimeout)// 设置连接主机服务超时时间
                .setConnectionRequestTimeout(connectionRequestTimeout == null ? 35000 : connectionRequestTimeout)// 设置连接请求超时时间
                .setSocketTimeout(socketTimeout == null ? 60000 : socketTimeout)// 设置读取数据连接超时时间
                .build();
        // 为httpPost实例设置配置
        httpPost.setConfig(requestConfig);
        if (paramsMap != null) {
          List<NameValuePair> paramList = new ArrayList<NameValuePair>();
          for (Map.Entry<String, String> param : paramsMap.entrySet()) {
            NameValuePair pair = new BasicNameValuePair(param.getKey(), param.getValue());
            paramList.add(pair);
          }
          httpPost.setEntity(new UrlEncodedFormEntity(paramList, ENCODING));
        }
        response = closeableHttpClient.execute(httpPost);
        if (response.getStatusLine().getStatusCode() == 200) {
          HttpEntity entity = response.getEntity();
          if (entity != null) {
            return EntityUtils.toString(entity);
          }
        }
      } catch (Exception e) {
        log.error("", e);
      } finally {
        try {
          if (response != null) {
            response.close();
          }
        } catch (IOException e) {
          log.error("", e);
        }
      }
      return null;
    }


    /**
     * 核酸对接功能
     *
     * @param httpPost
     * @param connectTimeout
     * @param connectionRequestTimeout
     * @param socketTimeout
     * @return
     */
    public static String postChronicResult(HttpPost httpPost, Integer connectTimeout,
        Integer connectionRequestTimeout, Integer socketTimeout) {
      CloseableHttpResponse response = null;
      try {
//            RequestConfig requestConfig =
//                    RequestConfig.custom().setConnectTimeout(connectTimeout == null ? 35000 : connectTimeout)// 设置连接主机服务超时时间
//                            .setConnectionRequestTimeout(connectionRequestTimeout == null ? 35000 : connectionRequestTimeout)// 设置连接请求超时时间
//                            .setSocketTimeout(socketTimeout == null ? 60000 : socketTimeout)// 设置读取数据连接超时时间
//                            .build();
//            // 为httpPost实例设置配置
//            httpPost.setConfig(requestConfig);
        response = closeableHttpClient.execute(httpPost);
        String respJson = EntityUtils.toString(response.getEntity(), Consts.UTF_8.name());
        log.info("接口返回结果:"+respJson);
        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
          return respJson;
        }else{
          log.error("核酸上报响应异常:"+respJson);
          return null;
        }
      } catch (Exception e) {
        log.error("", e);
      } finally {
        try {
          if (response != null) {
            response.close();
          }
        } catch (IOException e) {
          log.error("", e);
        }
      }
      return null;
    }

    public static String postByHis(String url, String params) {
      CloseableHttpResponse response = null;
      try {
        HttpPost httpPost = new HttpPost(url);
        httpPost.setHeader("content-type", "application/json");
        HttpEntity reqentity = new StringEntity(params, charset);
        httpPost.setEntity(reqentity);
        response = closeableHttpClient.execute(httpPost);
        if (response.getStatusLine().getStatusCode() == 200) {
          HttpEntity entity = response.getEntity();
          if (entity != null) {
            return EntityUtils.toString(entity, ENCODING);
          }
        }
      } catch (Exception e) {
        log.error("", e);
      } finally {
        try {
          if (response != null) {
            response.close();
          }
        } catch (IOException e) {
          log.error("", e);
        }
      }
      return null;
    }

    public static String postWithException(String url, String params) throws Exception {
      CloseableHttpResponse response = null;
      try {
        HttpPost httpPost = new HttpPost(url);
        HttpEntity reqentity = new StringEntity(params, charset);
        httpPost.setEntity(reqentity);
        response = closeableHttpClient.execute(httpPost);
        if (response.getStatusLine().getStatusCode() == 200) {
          HttpEntity entity = response.getEntity();
          if (entity != null) {
            return EntityUtils.toString(entity, ENCODING);
          } else {
            throw new Exception("未获取的响应内容");
          }
        } else {
          throw new Exception("请求响应码:" + response.getStatusLine().getStatusCode());
        }
      } catch (Exception e) {
        log.error("", e);
        throw e;
      } finally {
        try {
          if (response != null) {
            response.close();
          }
        } catch (IOException e) {
          log.error("", e);
        }
      }
    }

    public static String postWithHeader(String url, String params, Map<String, String> headerMap) {
      CloseableHttpResponse response = null;
      try {
        HttpPost httpPost = new HttpPost(url);
        for (String key : headerMap.keySet()) {
          httpPost.setHeader(key, headerMap.get(key));
        }
        HttpEntity reqentity = new StringEntity(params, charset);
        httpPost.setEntity(reqentity);
        response = closeableHttpClient.execute(httpPost);
        if (response.getStatusLine().getStatusCode() == 200) {
          HttpEntity entity = response.getEntity();
          if (entity != null) {
            return EntityUtils.toString(entity, ENCODING);
          }
        }
      } catch (Exception e) {
        log.error("", e);
      } finally {
        try {
          if (response != null) {
            response.close();
          }
        } catch (IOException e) {
          log.error("", e);
        }
      }
      return null;
    }

    public static String get(String url, String params) throws IOException {
      HttpGet httpGet = null;
      HttpResponse response;
      try {
        httpGet = new HttpGet(url + "?" + params);
        response = closeableHttpClient.execute(httpGet);
        HttpEntity entity = response.getEntity();
        if (entity != null) {
          return EntityUtils.toString(entity, "UTF-8");
        }
        return null;
      } catch (Exception e) {
        log.error("GetError", e);
        return e.getMessage();
      } finally {
        if (httpGet != null) {
          httpGet.releaseConnection();
        }
      }
    }

    public static String get(String url) throws IOException {
      HttpResponse response;
      HttpGet httpGet = null;
      try {
        httpGet = new HttpGet(url);
        response = closeableHttpClient.execute(httpGet);
        HttpEntity entity = response.getEntity();
        if (entity != null) {
          return EntityUtils.toString(entity, "UTF-8");
        }
        return null;
      } catch (Exception e) {
        e.printStackTrace();
        return e.getMessage();
      } finally {
        if (httpGet != null) {
          httpGet.releaseConnection();
        }
      }
    }

    public static String get(String url, Map<String, String> paramsMap) {
      CloseableHttpResponse response = null;
      HttpGet httpget = null;
      try {
        StringBuffer sBuffer = new StringBuffer();
        if (paramsMap != null && paramsMap.size() != 0) {
          for (Map.Entry<String, String> param : paramsMap.entrySet()) {
            sBuffer.append(param.getKey() + "=" + param.getValue() + "&");
          }
        }
        url = url + "?" + sBuffer.toString();
        httpget = new HttpGet(url);
        response = closeableHttpClient.execute(httpget);
        if (response.getStatusLine().getStatusCode() == 200) {
          HttpEntity entity = response.getEntity();
          if (entity != null) {
            return EntityUtils.toString(entity);
          }
        }
      } catch (Exception e) {
        log.error("", e);
      } finally {
        if (httpget != null) {
          httpget.releaseConnection();
        }
      }
      return null;
    }

    public static String postLink(String url, Map<String, String> paramsMap) {
      CloseableHttpResponse response = null;
      HttpPost method = null;
      try {
        StringBuffer stringBuffer = new StringBuffer();
        if (paramsMap != null) {
          for (Map.Entry<String, String> param : paramsMap.entrySet()) {
            stringBuffer.append("&" + param.getKey() + "=" + param.getValue());
          }
        }
        url = url + stringBuffer.toString();
        method = new HttpPost(url);
        response = closeableHttpClient.execute(method);
        if (response.getStatusLine().getStatusCode() == 200) {
          HttpEntity entity = response.getEntity();
          if (entity != null) {
            return EntityUtils.toString(entity);
          }
        }
      } catch (Exception e) {
        log.error("", e);
      } finally {
        if (method != null) {
          method.releaseConnection();
        }
      }
      return null;
    }

    public static String postLocalXForm(String url, List<NameValuePair> params) {
      HttpPost httpPost;
      CloseableHttpResponse response = null;
      try {
        httpPost = new HttpPost(url);
        httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
        httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
        response = closeableHttpClient.execute(httpPost);
        if (response.getStatusLine().getStatusCode() == 200) {
          HttpEntity entity = response.getEntity();
          if (entity != null) {
            return EntityUtils.toString(entity);
          }
        }
      } catch (Exception e) {
        log.error("", e);
      } finally {
        try {
          if (response != null) {
            response.close();
          }
        } catch (IOException e) {
          log.error("", e);
        }
      }
      return null;
    }

    public static String postLocal(String url, String parm) {
      CloseableHttpResponse response = null;
      HttpPost httpPost;
      try {
        httpPost = new HttpPost(url);
        httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
        StringEntity data = new StringEntity(parm, StandardCharsets.UTF_8);
        httpPost.setEntity(data);
        response = closeableHttpClient.execute(httpPost);
        if (response.getStatusLine().getStatusCode() == 200) {
          HttpEntity entity = response.getEntity();
          if (entity != null) {
            return EntityUtils.toString(entity);
          }
        }
      } catch (Exception e) {
        log.error("", e);
      } finally {
        try {
          if (response != null) {
            response.close();
          }
        } catch (IOException e) {
          log.error("", e);
        }
      }
      return null;
    }

    public static String get(String url, Map<String, String> paramsMap, Map<String, String> headerMap)
        throws IOException {
      CloseableHttpResponse response = null;
      try {
        StringBuffer sBuffer = new StringBuffer();
        if (paramsMap != null && paramsMap.size() != 0) {
          for (Map.Entry<String, String> param : paramsMap.entrySet()) {
            sBuffer.append(param.getKey() + "=" + param.getValue() + "&");
          }
        }

        if (sBuffer != null) {
          url = url + "?" + sBuffer.deleteCharAt(sBuffer.length() - 1).toString();
        }
        HttpGet httpget = new HttpGet(url);
        httpget.setHeader("content-Type", "application/json;charset=utf-8");
        for (String key : headerMap.keySet()) {
          httpget.setHeader(key, headerMap.get(key));
        }
        response = closeableHttpClient.execute(httpget);
        if (response.getStatusLine().getStatusCode() == 200) {
          HttpEntity entity = response.getEntity();
          if (entity != null) {
            return EntityUtils.toString(entity);
          }
        } else {
          log.error("当前请求响应码  " + response.getStatusLine().getStatusCode());
        }
      } catch (Exception e) {
        log.error("", e);
      } finally {
        try {
          if (response != null) {
            response.close();
          }
        } catch (IOException e) {
          log.error("", e);
        }
      }
      return null;
    }


    /**
     * 华为接口调用
     * <p>
     * form表单类型
     * <p>
     * 场景：auth快速登录，token刷新，授权取消
     *
     * @param url
     * @param params
     * @param headerMap
     *            Content-Type应该包含
     * @return
     */
    public static String hwFormPost(String url, List<NameValuePair> params, Map<String, String> headerMap) {
      CloseableHttpResponse response = null;
      try {
        HttpPost httpPost = new HttpPost(url);
        httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
        if (headerMap != null && headerMap.size() > 0) {
          for (String key : headerMap.keySet()) {
            httpPost.setHeader(key, headerMap.get(key));
          }
        }

        httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
        response = closeableHttpClient.execute(httpPost);
        // if (response.getStatusLine().getStatusCode() == 200) {
        HttpEntity entity = response.getEntity();
        if (entity != null) {
          return EntityUtils.toString(entity, ENCODING);
        }
        // }
      } catch (Exception e) {
        log.error("", e);
      } finally {
        try {
          if (response != null) {
            response.close();
          }
        } catch (IOException e) {
          log.error("", e);
        }
      }
      return null;
    }

    /**
     * 华为接口调用
     * <p>
     * json类型
     * <p>
     * 场景:各种业务接口调用
     *
     * @param url
     * @param params
     * @param headerMap
     * @return
     */
    public static String hwJsonPost(String url, String params, Map<String, String> headerMap) {
      CloseableHttpResponse response = null;
      try {
        HttpPost httpPost = new HttpPost(url);
        httpPost.setHeader("Content-Type", "application/json");
        if (headerMap != null && headerMap.size() > 0) {
          for (String key : headerMap.keySet()) {
            httpPost.setHeader(key, headerMap.get(key));
          }
        }

        HttpEntity reqEntity = new StringEntity(params, charset);
        httpPost.setEntity(reqEntity);
        response = closeableHttpClient.execute(httpPost);
        // if (response.getStatusLine().getStatusCode() == 200) {
        HttpEntity entity = response.getEntity();
        if (entity != null) {
          return EntityUtils.toString(entity, ENCODING);
        }
        // }
      } catch (Exception e) {
        log.error("", e);
      } finally {
        try {
          if (response != null) {
            response.close();
          }
        } catch (IOException e) {
          log.error("", e);
        }
      }
      return null;
    }

    public static void gcConnection(){
      closeableHttpClient.getConnectionManager().closeExpiredConnections();
      closeableHttpClient.getConnectionManager().closeIdleConnections(30, TimeUnit.SECONDS);
    }

    public static void main(String[] args) {
      // http请求his医嘱接口
//      Map<String, Object> map = new HashMap<>();
//      map.put("patientId", "z000130566300");
//      map.put("startTime", 1622649600000L);
//      map.put("endTime", 1630382574050L);//1630303199000L+3600000*8+2926999);
//
//      // {patientId=z000130566300, startTime=1622649600000, endTime=1630382574050}  1630382841245000L   1630339201000L
//      String json = HttpClient
//          .post("http://www.wxjm1ph.cn:8095/api/QueryPatientPACSinfo", JSON.toJSONString(map));
//      JSONObject object = JSON.parseObject(json);
//      System.out.println(object);

        String json = HttpClient
          .post("http://www.wxjm1ph.cn:8095/api/pushDataQuery", JSON.toJSONString(""));
    }
}
